<?php

namespace app\index\controller;

use app\admin\controller\Order;
use app\common\entity\Config;
use app\common\entity\Goods;
use app\common\entity\GoodsOrders;
use app\common\entity\MywalletLog;
use app\common\entity\Orders;
use app\common\entity\Proportion;
use app\common\entity\ShopUserAddress;
use app\common\shop\OrderModel;
use app\common\shop\RechargeLogModel;
use app\index\model\SendCode;
use think\Controller;
use think\Db;
use think\Request;
use app\common\entity\User;
use think\captcha\Captcha;
use app\common\entity\Message;
use app\common\entity\Image;
use app\common\entity\Article;
use app\common\entity\GoodsCategory;
use think\Log;


class Apppay extends Controller
{
    /*支付回调*/
    public function payback(Request $request)
    {
        //这是签名验证串，在 App配置 查询或重置
        $secretKey = "9nIclnLr0DMycAbmpz9glpGnFR5tlDnV";

        // print_r($_POST);

        $kv = array();
        foreach ($_POST as $key => $val) {
            $kv[$key] = $val;
        }
        ksort($kv);
        reset($kv);
        $param = '';
        foreach ($kv AS $key => $val) {
            if ($key != 'sign') {
                $param .= "$key=$val&";
            }
        }

        $param = substr($param, 0, -1) . $secretKey;

        $verify_result = (md5($param) == strtolower($kv["sign"]));

        if ($verify_result) {
            //获取有效的参数值
            $tradeid = $kv["tradeid"];  //支付平台上的交易号
            $orderid = $kv["orderid"];  //订单号
            $amount = $kv["amount"];  //支付金额
            $channel = $kv["channel"];  //支付渠道, 0 微信，1 支付宝

            //用上面的参数处理支付成功的后续业务
            //请在这里自由发挥，尽量不要修改其他地方
            //do something...
            //更新订单状态 - 付款成功
            $str = substr($orderid , 0 , 2);
            if($str == 'SH'){
                // 购买商品
                // $this->shoporder($tradeid,$orderid,$amount,$channel);
                $order = OrderModel::getOrdersnInfo($orderid);
                if(!$order) return json(['code' =>1, 'msg' => '订单不存在']);
                if($order['status'] != 0) return json(['code'=>1,'msg'=>'订单已付款']);


                Db::startTrans();
                try{

                    /*1=>'微信支付',
                    2=>'支付宝支付',
                    3=>'代金券支付',
                    4=>'福币支付',
                    5=>'余额支付',*/
                    if($channel == 0){//支付渠道, 0 微信，1 支付宝
                        $paytype = 1;
                    }elseif($channel == 1){
                        $paytype = 2;
                    }
                    /*如果是代金券商品，直接完成订单-得到代金券*/
                    if($order['shoptype'] == 4){
                        // $allmoney = $order['total']+$order['blessnumber'];
                        // MywalletLog::addLog($order['uid'], $allmoney, 2 , '购买代金券', 2, 1);
                        //OrderModel::taskOrder($order['id']);// 完成订单
                    }
                    // 修改订单-完成付款
                    OrderModel::payOrder($order['id'],$paytype,0,$order);
                    Db::commit();
                    echo "OK";
                } catch (\Exception $e) {
                    Db::rollback();
                    return json(['code' => '1', 'msg' => '系统错误,请联系技术人员处理'.$e->getMessage()]);
                }
            }elseif($str == 'RE'){
                // 充值
                $order = RechargeLogModel::where('sn',$orderid)->find();
                if($order['status'] != 0){
                    echo "OK";
                    return;
                }
                $allmoney = $order['number'];
                Db::startTrans();
                try{
                    RechargeLogModel::where('id',$order['id'])->setField(['status'=>1]);
                    MywalletLog::addLog($order['uid'], $allmoney, 4 , '会员充值', 7, 1);
                    Db::commit();
                    echo "OK";
                }catch (\Exception $e){
                    Db::rollback();
                    return json(['code'=>1,'msg'=> '系统错误,请联系技术人员处理-'.$e->getMessage()]);
                }
            }

            //处理成功后，http 要返回 OK 字符，否则你的服务器可能会多次收到确认通知
        } else {
            //签名验证失败
            return json(['code' => 2, 'msg' => '验签失败']);
        }
    }

    /**
     * [处理订单]
     * @param
     * @return
     */
    public function shoporder($tradeid,$orderid,$amount,$channel){

    }


    public function paycallback(Request $request)
    {

        //这是签名验证串，在 App配置 查询或重置
        Db::name('pay_log')->insert(['data'=>json_encode($_POST)]);
        $secretKey  = '5P2TywdcNykBYbWfPptcx1pMkfXYTk8S';
        //发送通知时的 Unix 时间戳，可用于处理通知过期策略
        $timestamp = intval($_POST["timestamp"]);
        //假定15分钟内有效
        if (($timestamp + 15 * 60) < date_timestamp_get(date_create())) {
            //通知已过期
            throw new \Exception('通知已过期');
            return;
        }
        $kv = array();
        //遍历 form 表单
        foreach ($_POST as $key => $val) {
            $kv[$key] = $val;
        }
        ksort($kv);
        reset($kv);
        $param = '';
        foreach ($kv AS $key => $val) {
            if ($key != 'sign') {
                $param .= "$key=$val&";
            }
        }
        $param = substr($param, 0, -1).$secretKey;
        $verify_result = (md5($param) == strtolower($kv["sign"]));
        if(!$verify_result){
            throw new \Exception('验签不通过');
            return false;
        }
        $order_number = $request->param('orderid');
        $orderInfo = Orders::where('order_number',$order_number)->find();
        if ($orderInfo['status'] != 0) {
            throw new \Exception('订单状态错误');
            return json(['code' => 1, 'message' => '订单状态错误']);
        }


        $user_id = 0;
        Orders::where('order_number',$order_number)->update(['pay_time'=>time(),'status'=>1]);
        $orders =  Orders::where('order_number',$order_number)->select();
        $pps_stock = [];$order_stock = [];

        foreach($orders as $k=>$v){
            $user_id = $v['user_id'];
            $goods = Goods::where('id',$v['goods_id'])->find();

            $order_stock[] = [
                'id'=>$v['goods_id'],
                'goods_num'=>$goods['goods_num'] - $v['pay_num'],
            ];
            if($v['key']){
                $pps = Db::name('goods_pps')->where(['gid'=>$v['goods_id'],'key'=>$v['key']])->find();

                $pps_stock[] = [
                    'gid'=>$v['goods_id'],
                    'key'=>$v['key'],
                    'stock'=>$pps['stock'] - $v['pay_num']
                ];
                /* if($pps['stock'] - $v['pay_num'] < 0){

                     print_r([$pps , $v['pay_num'],$v['goods_id']]);
                     return json(['code' => 1, 'message' => '库存不足']);
                 }*/
            }
            #@todo 送gyg
            $gyg =  bcmul(\app\common\entity\Mywallet::cnyToGyg($goods['goods_prices']),$v['pay_num'],2);
            MywalletLog::addLog($v['user_id'], $gyg, 2, '购买商品赠送', 1, 1);
            foreach($order_stock as $k=>$v){
                Goods::where('id',$v['id'])->update(['goods_num'=>$v['goods_num']]);
            }
            foreach($pps_stock as $k=>$v){
                Db::name('goods_pps')->where(['gid'=>$v['gid'],'key'=>$v['key']])->update(['stock'=>$v['stock']]);
            }


        }

        User::upLevel($user_id);
        echo "OK";
    }



    public function WXpaycallback(Request $request)
    {

        //这是签名验证串，在 App配置 查询或重置
        $xml = file_get_contents('php://input','r');
        $data = $this->toArray($xml);

        Db::name('pay_log')->insert(['data'=>json_encode($data)]);

        // 获取xml
        $xml=file_get_contents('php://input', 'r');
        // 转成php数组
        $data=$this->toArray($xml);
        // 保存原sign
        $data_sign=$data['sign'];
        // sign不参与签名
        unset($data['sign']);
        $sign=$this->makeSign($data);
        // 判断签名是否正确  判断支付状态
        if ($sign===$data_sign && $data['return_code']=='SUCCESS' && $data['result_code']=='SUCCESS') {
            $result=$data;
        }else{
            $result=false;
        }
        // 返回状态给微信服务器
        if ($result) {
            echo '<xml>
  <return_code><![CDATA[SUCCESS]]></return_code>
  <return_msg><![CDATA[OK]]></return_msg>
</xml>';

        }else{

            echo '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
        }

        $order_number = $data['out_trade_no'];
        $orderInfo = Orders::where('order_number',$order_number)->find();
        if ($orderInfo['status'] != 0) {
            throw new \Exception('订单状态错误');
            return json(['code' => 1, 'message' => '订单状态错误']);
        }


        $user_id = 0;
        Orders::where('order_number',$order_number)->update(['pay_time'=>time(),'status'=>1]);
        $orders =  Orders::where('order_number',$order_number)->select();
        $pps_stock = [];$order_stock = [];

        foreach($orders as $k=>$v){
            $user_id = $v['user_id'];
            $goods = Goods::where('id',$v['goods_id'])->find();

            $order_stock[] = [
                'id'=>$v['goods_id'],
                'goods_num'=>$goods['goods_num'] - $v['pay_num'],
            ];
            if($v['key']){
                $pps = Db::name('goods_pps')->where(['gid'=>$v['goods_id'],'key'=>$v['key']])->find();

                $pps_stock[] = [
                    'gid'=>$v['goods_id'],
                    'key'=>$v['key'],
                    'stock'=>$pps['stock'] - $v['pay_num']
                ];
                /* if($pps['stock'] - $v['pay_num'] < 0){

                     print_r([$pps , $v['pay_num'],$v['goods_id']]);
                     return json(['code' => 1, 'message' => '库存不足']);
                 }*/
            }
            #@todo 送gyg
            $gyg =  bcmul(\app\common\entity\Mywallet::cnyToGyg($goods['goods_prices']),$v['pay_num'],2);
            MywalletLog::addLog($v['user_id'], $gyg, 2, '购买商品赠送', 1, 1);
            foreach($order_stock as $k=>$v){
                Goods::where('id',$v['id'])->update(['goods_num'=>$v['goods_num']]);
            }
            foreach($pps_stock as $k=>$v){
                Db::name('goods_pps')->where(['gid'=>$v['gid'],'key'=>$v['key']])->update(['stock'=>$v['stock']]);
            }


        }

        $a = '{"appid":"wx5078cb1eb1561fdf",
"attach":"giao\u724c\u85af\u4ed4",
"bank_type":"OTHERS",
"cash_fee":"1",
"fee_type":"CNY",
"is_subscribe":"N",
"mch_id":"1603328167",
"nonce_str":"e64605bc3c1846a8a969fb10350f3e9a",
"openid":"oqYan57hM-fxxOuRt6AakRFmBwWY",
"out_trade_no":"2020102621574910394014",
"result_code":"SUCCESS",
"return_code":"SUCCESS",
"sign":"86C02D88AF61E7C8172D7FFBF5C70A54",
"time_end":"20201026103948",
"total_fee":"1","trade_type":"APP","transaction_id":"4200000820202010263708376694"}';
    }


    public function toArray($xml){
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $result= json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $result;
    }

    /**
     * 生成签名
     * @return 签名，本函数不覆盖sign成员变量，如要设置签名需要调用SetSign方法赋值
     */
    public function makeSign($data)
    {
        // 去空
        $data=array_filter($data);
        //签名步骤一：按字典序排序参数
        ksort($data);
        //将数组转成url形式
        $string_a=http_build_query($data);
        $string_a=urldecode($string_a);
        //签名步骤二：在string后加入KEY
        $string_sign_temp=$string_a."&key="."asjsxhangsbaghs154845454jsha8454";
        //签名步骤三：MD5加密
        $sign = md5($string_sign_temp);
        // 签名步骤四：所有字符转为大写
        $result=strtoupper($sign);
        return $result;
    }
}
